package com.nlelpct.manage.controller;

import com.alibaba.fastjson2.JSON;
import com.nlelpct.manage.constant.ResponseCode;
import com.nlelpct.manage.model.entity.SysRole;
import com.nlelpct.manage.model.query.InsertAndUpdateRoleQuery;
import com.nlelpct.manage.model.query.RolePageQuery;
import com.nlelpct.manage.model.vo.*;
import com.nlelpct.manage.service.IRoleService;
import com.nlelpct.manage.utils.Nap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author :小马
 * @date : 2023-07-19
 */
@Slf4j
@RestController
@RequestMapping("/role")
public class RoleController {

    private final IRoleService roleService;

    private final StringRedisTemplate stringRedisTemplate;

    @Autowired
    public RoleController(IRoleService roleService, StringRedisTemplate stringRedisTemplate) {
        this.roleService = roleService;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
     * 分页查询
     */
    @PreAuthorize("hasRole('admin')")
    @PostMapping("/roleQueryList")
    public ResponseResult<PageResultVo<SysRole>> queryRoleList(@RequestBody RolePageQuery rolePageQuery) {
        return roleService.queryRolePageList(rolePageQuery);
    }

    /**
     * 添加角色-更新角色时判断角色名称是否重复
     */
    @PreAuthorize("hasRole('admin')")
    @PostMapping("/validateRoleName")
    public ResponseResult<Boolean> validateRoleName(@RequestBody @Valid InsertAndUpdateRoleQuery validateRoleNameQuery) {
        return roleService.validateRoleName(validateRoleNameQuery);
    }

    /**
     * 添加角色
     */
    @PreAuthorize("hasRole('admin')")
    @PostMapping("/addRole")
    public ResponseResult<String> addRole(@RequestBody @Valid InsertAndUpdateRoleQuery insertRoleQuery) {
        synchronized (stringRedisTemplate) {
            String key = "RoleController.addRole" + JSON.toJSONString(insertRoleQuery);
            if (!ObjectUtils.isEmpty(stringRedisTemplate.opsForValue().get(key))) {
                new Nap(0.3);
            }
            stringRedisTemplate.opsForValue().set(key, key, 300L, TimeUnit.MILLISECONDS);
        }
        ResponseResult<Boolean> booleanResponseResult = roleService.validateRoleName(insertRoleQuery);
        if (!booleanResponseResult.getData()) {
            return ResponseResult.error(ResponseCode.ORDINARY_FAIL, "添加角色失败,名称重复.");
        }
        try {
            roleService.insertRole(insertRoleQuery);
        } catch (Exception e) {
            log.error("添加角色时出现异常,具体异常信息如下: ");
            e.printStackTrace();
            return ResponseResult.error(ResponseCode.ORDINARY_FAIL, "添加角色信息失败,请联系系统管理员");
        }
        return ResponseResult.success("添加角色成功");
    }


    /**
     * 更新前获取角色信息
     */
    @PreAuthorize("hasRole('admin')")
    @GetMapping("/getRoleInfoForUpdate/{roleId}")
    public ResponseResult<InsertAndUpdateRoleQuery> getRoleInfoByUpdate(@PathVariable("roleId") String roleId) {
        return roleService.getRoleInfoByUpdate(roleId);
    }

    /**
     * 更新角色
     */
    @PreAuthorize("hasRole('admin')")
    @PostMapping("/updateRoleInfo")
    public ResponseResult<String> updateRoleInfo(@RequestBody @Valid InsertAndUpdateRoleQuery updateRoleQuery) {
        ResponseResult<Boolean> booleanResponseResult = roleService.validateRoleName(updateRoleQuery);
        if (!booleanResponseResult.getData()) {
            return ResponseResult.error(ResponseCode.ORDINARY_FAIL, "角色名称重复");
        }
        try {
            roleService.updateRole(updateRoleQuery);
        } catch (Exception e) {
            log.error("更新角色时出现异常,具体异常信息如下: ");
            e.printStackTrace();
            ResponseResult.error(ResponseCode.ORDINARY_FAIL, "更新角色信息失败,请联系系统管理员");
        }
        return ResponseResult.success("编辑角色信息成功");
    }

    /**
     * 获取角色的菜单权限
     */
    @PreAuthorize("hasRole('admin')")
    @GetMapping("/getMenuPermissionsByRole/{roleId}")
    public ResponseResult<MenuPermissionsVo> getMenuPermissionsByRole(@PathVariable("roleId") String roleId) {
        return roleService.getMenuByRoleId(roleId);
    }

    /**
     * 修改角色的数据权限
     */
    @PreAuthorize("hasRole('admin')")
    @PostMapping("/changeMenuPermissionsByRole")
    public ResponseResult<String> changeMenuPermissionsByRole(@RequestBody @Valid MenuPermissionsVo menuPermissionsVo) {
        try {
            roleService.changeMenuPermissionsByRole(menuPermissionsVo);
        } catch (Exception e) {
            log.error("修改角色的菜单权限异常,具体异常信息如下: ");
            e.printStackTrace();
            return ResponseResult.error(ResponseCode.ORDINARY_FAIL, "修改角色的菜单权限出错,请联系系统管理员");
        }
        return ResponseResult.success("修改成功");
    }

    /**
     * 获取角色的数据权限
     */
    @PreAuthorize("hasRole('admin')")
    @GetMapping("/getDataPermissionsByRole/{roleId}")
    public ResponseResult<DataPermissionsVo> getDataPermissionsByRole(@PathVariable("roleId") String roleId) {
        return roleService.getDataPermissionsByRoleId(roleId);
    }

    /**
     * 修改角色的数据权限
     */
    @PreAuthorize("hasRole('admin')")
    @PostMapping("/changeDataPermissionsByRole")
    public ResponseResult<String> changeDataPermissionsByRole(@RequestBody @Valid DataPermissionsVo dataPermissionsVo) {
        try {
            roleService.changeDataPermissionsByRole(dataPermissionsVo);
        } catch (Exception e) {
            log.error("修改角色的数据权限异常,具体异常信息如下: ");
            e.printStackTrace();
            return ResponseResult.error(ResponseCode.ORDINARY_FAIL, "修改角色的数据权限出错,请联系系统管理员");
        }
        return ResponseResult.success("修改成功");
    }

    /**
     * 删除角色时校验是否可以删除 -- 是否有被流程引用
     */
    @PreAuthorize("hasRole('admin')")
    @GetMapping("/deleteRoleValidate/{roleId}")
    public ResponseResult<Boolean> deleteRoleValidate(@PathVariable("roleId") String roleId) {
        return roleService.deleteRoleValidate(roleId);
    }

    /**
     * 删除角色
     */
    @PreAuthorize("hasRole('admin')")
    @GetMapping("/deleteRole/{roleId}")
    public ResponseResult<String> deleteRole(@PathVariable("roleId") String roleId) {
        ResponseResult<Boolean> booleanResponseResult = roleService.deleteRoleValidate(roleId);
        if (!booleanResponseResult.getData()) {
            return ResponseResult.error(ResponseCode.ORDINARY_FAIL, "当前角色不允许删除");
        }
        try {
            roleService.removeRole(roleId);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(ResponseCode.ORDINARY_FAIL, "删除角色出错,请联系系统管理员");
        }
        return ResponseResult.success("删除角色完成");
    }


    /**
     * 获取企业内配置的角色信息
     */
    @PreAuthorize("hasRole('admin')")
    @GetMapping("/getRoleInfoForCompany")
    public ResponseResult<List<RoleInfoForCompanyVo>> getRoleInfoForCompany() {
        return roleService.getRoleInfoForCompany();
    }
}
